package com.cosyhut.blocks.engine;

import java.util.ArrayList;
import java.util.Iterator;

import com.cosyhut.blocks.jode.*;

import com.jme.renderer.*;

/**
 * 
 * @author TimWorks
 * Jan 23, 2007
 * 
 * the engine class handles ODE related staff
 */
public class Engine {
	private static Engine instance = null;

	protected Engine() {
		this.init();
	}

	public static Engine get() {
		if (instance == null) {
			instance = new Engine();
		}
		return instance;
	}

	boolean _init = false;

    private ODEWorld _world = null;
    private float _stepSize = 0;
    private SWIGTYPE_p_dxSpace _space = null;
    private SWIGTYPE_p_dxSpace _envSpace = null;
    
    private ArrayList<BRobot> _robots;


    // collision
    //JavaCollision collision;
    // Helper class to read / write collision data (DirectBuffer)
    //Contact contact;

	private void init() {
		initWorld();
		
        this._robots = new ArrayList<BRobot>();

        jode.ODESpaceInit(this._world.getWorld());
        
        //collision = new JavaCollision(this._world);
        // Setup DirectBuffers reader
        //contact =
        //    new Contact(
        //        collision.getContactIntBuffer(),
        //        collision.getContactFloatBuffer());
		this._init = true;
	}
	
	public void setFPS(int fps) {
        this._stepSize = 1.0f/fps;
	}
	
	public boolean isInited() {
		return this._init;
	}
	
	public void update() {
        // Collide objects in given space
        //collision.collide(this._space);
        
//        collision.collide2((int)this._envSpace.getId().getSwigCPtr(), (int)this._blockSpace.getId().getSwigCPtr());

        // Read & modify contact information
//        iterateContacts();

        // Add all contacts to contact jointGroup
        //collision.applyContacts();

        jode.ODESpaceCollide(this._space);

        this._world.step(this._stepSize);
		
        // -- update all robots
        Iterator i = this._robots.iterator();
        while(i.hasNext()) {
        	BRobot robot = (BRobot) i.next();
        	robot.update();
        }
	}

	/**
	 * the debug function
	 * @param renderer r
	 */
	public void drawPhysics (Renderer r) {
		// 
	}	

    private void initWorld() {
		System.loadLibrary("jode");
		this._world = new ODEWorld();
        setFPS(33);

        // Create space that contains all of our geoms / bodies
        this._space = jode.dHashSpaceCreate(null);;
        this._envSpace = jode.dHashSpaceCreate(this._space);;
    }

    public void addRobot(BRobot r) {
    	this._robots.add(r);
    }
    public BRobot getRobot() {
    	return this._robots.get(0);
    }
    //--------------------------------------------------------------------------
    public ODEWorld getWorld() {
        return this._world;
    }
    public SWIGTYPE_p_dxSpace getSpace() {
        return this._space;
    }
    public SWIGTYPE_p_dxSpace getEnvSpace() {
        return this._envSpace;
    }
    
}
